package users

import (
	"context"
	_ "github.com/gogf/gf/contrib/nosql/redis/v2"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/golang-jwt/jwt/v4"
	"shenmawl/internal/dao"
	"shenmawl/internal/model/do"
	"shenmawl/internal/model/entity"
	"shenmawl/utility"
	"time"
)

type RegisterInput struct {
	Username string
	Password string
	Phone    string
	Email    string
	Client   string
}
type UserClaims struct {
	Username string
	jwt.RegisteredClaims
}

type UserInfo struct {
	Status int    //1为登录,0为离线，-1为封号
	Token  string //登录成功生成的token
	Client string //登录平台
}

func (u *NoRBACUsers) Login(ctx context.Context, username, password, client string) (tokenString string, err error) {
	var user entity.SysUser
	err = dao.SysUser.Ctx(ctx).Where("user_name", username).Scan(&user)
	if err != nil {
		return "", utility.Err.Skip(10001)
	}

	if user.UserId == 0 {
		return "", utility.Err.Skip(10001)
	}

	// 将密码加密后与数据库中的密码进行比对
	if user.Password != password {
		return "", utility.Err.Skip(10002)
	}

	// 生成token
	userClaims := &UserClaims{
		Username: user.UserName,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(6 * time.Hour)),
		},
	}

	jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, userClaims)
	token, _ := jwtToken.SignedString(utility.JwtKey)

	// 将登录信息存入redis
	userInfo := g.Map{
		"Status": 1,
		"Token":  token,
		"Client": client,
	}

	// 存储到Redis
	_, err = g.Redis().HSet(ctx, username, userInfo)
	if err != nil {
		g.Log().Fatal(ctx, err)
		return "", utility.Err.Skip(92003)
	}
	//设置过期时间
	_, err = g.Redis().Expire(ctx, username, 21600)
	return jwtToken.SignedString(utility.JwtKey)
}
func (u *NoRBACUsers) Register(ctx context.Context, username, password, phone, email, client string) error {
	if username == "" {
		return utility.Err.Skip(19001)
	}
	count, err := dao.GameUser.Ctx(ctx).Where("username", username).Count()
	if err != nil {
		return utility.Err.Skip(92002)
	}
	if count > 0 {
		return utility.Err.Skip(91001)
	}

	_, err = dao.GameUser.Ctx(ctx).Data(do.GameUser{
		Username:     username,
		PasswordHash: password,
		PhoneNumber:  phone,
		Email:        email,
		Client:       client,
		CreateTime:   gtime.Now(),
		UpdateTime:   gtime.Now(),
		LoginTime:    gtime.Now(),
	}).Insert()
	if err != nil {
		return utility.Err.Skip(91003)
	}
	return nil
}
func (u *Users) UserInfo(ctx context.Context) (user *entity.SysUser, err error) {
	user = new(entity.SysUser)
	tokenString, _ := g.RequestFromCtx(ctx).Request.Cookie("jwt")

	tokenClaims, _ := jwt.ParseWithClaims(tokenString.String(), &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
		return utility.JwtKey, nil
	})

	if claims, ok := tokenClaims.Claims.(*UserClaims); ok && tokenClaims.Valid {
		err = dao.SysUser.Ctx(ctx).Where("user_id", claims.Username).Scan(&user)
	}
	return
}

func (u *Users) UserList(ctx context.Context) (user []entity.SysUser, count int, err error) {
	// 创建一个空的SysUser实体用于存储查询结果
	user = make([]entity.SysUser, 0)

	// 从上下文中获取HTTP请求对象，并尝试获取名称为"jwt"的Cookie
	//tokenString, _ := g.RequestFromCtx(ctx).Request.Cookie("jwt")

	err = dao.SysUser.Ctx(ctx).ScanAndCount(&user, &count, true)
	//fmt.Println(gconv.String(&user))
	// 返回查询到的用户信息和可能的错误
	return
}
